package com.hakim.wfb.customer.service.biz;

import com.hakim.wfb.admin.params.interest.GetConsumeInterestParam;
import com.hakim.wfb.bean.BenefitRecord;
import com.hakim.wfb.bean.ConsumeInterest;
import com.hakim.wfb.bean.ConsumeRecord;
import com.hakim.wfb.bean.ConsumeRule;
import com.hakim.wfb.bean.CreditPoint;
import com.hakim.wfb.bean.PointOrder;
import com.hakim.wfb.bean.User;
import com.hakim.wfb.biz.BenefitRecordBiz;
import com.hakim.wfb.biz.ConsumeInterestBiz;
import com.hakim.wfb.biz.ConsumeRecordBiz;
import com.hakim.wfb.biz.ConsumeRuleBiz;
import com.hakim.wfb.biz.CreditPointBiz;
import com.hakim.wfb.biz.PointOrderBiz;
import com.hakim.wfb.biz.UserBiz;
import com.hakim.wfb.common.enums.PointTypeEnum;
import com.hakim.wfb.common.enums.TransTypeEnum;
import com.hakim.wfb.common.enums.UserInvestStatusEnum;
import com.hakim.wfb.common.serial.SerialNoGenerator;
import com.hakim.wfb.common.serial.UUIDGenerator;
import com.hakim.wfb.common.util.DateUtils;
import com.hakim.wfb.customer.enums.ErrorCodeEnum;
import com.hakim.wfb.customer.service.task.StaticProfitTask;
import com.hkfs.fundamental.exception.HkfsBizException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * Created by Administrator on 2017/7/3.
 */
@Service("staticProfitBizService")
public class StaticProfitBizService {

    private static Logger logger = LoggerFactory.getLogger(StaticProfitTask.class);

    @Autowired
    private UserBiz userBiz;

    @Autowired
    private CreditPointBiz creditPointBiz;

    @Autowired
    private BenefitRecordBiz benefitRecordBiz;

    @Autowired
    private ConsumeInterestBiz consumeInterestBiz;

    @Autowired
    private PointOrderBiz pointOrderBiz;

    @Autowired
    private ConsumeRuleBiz consumeRuleBiz;

    @Autowired
    private ConsumeRecordBiz consumeRecordBiz;

    @Transactional()
    public void run(ConsumeRecord consumeRecord) {

        if (consumeRecord == null) {
            return;
        }
        String nowStr = DateUtils.getNow() + " ";
        BenefitRecord benefitRecord = benefitRecordBiz.getBenefitRecord(consumeRecord.getTid());
        //已返还
        if (benefitRecord != null) {
            return;
        }
        User user = userBiz.getUser(consumeRecord.getCrUser());
        if (user == null) {
            logger.warn(nowStr + "没有用户 id： " + consumeRecord.getCrUser());
            return;
        }
        CreditPoint creditPoint = creditPointBiz.getCreditPointById(consumeRecord.getCrUser());
        if (creditPoint == null) {
            logger.warn(nowStr + "没有用户 id： " + consumeRecord.getCrUser());
            return;
        }
        ConsumeRule consumeRule = consumeRuleBiz.getConsumeRule(consumeRecord.getCrCustRule());
        if (creditPoint == null) {
            logger.warn(nowStr + "没有此类消费模式 id： " + consumeRecord.getCrCustRule());
            return;
        }

        GetConsumeInterestParam getConsumeInterestParam = new GetConsumeInterestParam();
        getConsumeInterestParam.setRuleId(consumeRecord.getCrCustRule());
        getConsumeInterestParam.setInterestDateTime(DateUtils.getNextDay(-1));
        ConsumeInterest interestOfBeforeDay = consumeInterestBiz
                .getConsumeInterest(getConsumeInterestParam);
        if (interestOfBeforeDay == null) {
            logger.warn(nowStr + "消费规则Id：" + consumeRecord.getCrCustRule() + " 需要设置静态积分日息！");
            return;
        }
        String orderNo = SerialNoGenerator.getProfitOrderNo(user.getUserPhone());

        //计算当日静态收益
        double profit = interestOfBeforeDay.getInterest().doubleValue() / 100 * consumeRecord
                .getCrCustPoint();

        consumeRecord.setCrRewardSum(consumeRecord.getCrRewardSum() + profit);
        consumeRecord.setCrRewardRemainCount(consumeRecord.getCrRewardRemainCount() - 1);
        consumeRecordBiz.update(consumeRecord);
        logger.info(nowStr + "静态积分分红，用户：" + user.getUserCode() + "，消费记录更新。");

        //积分总表更新增加新的积分
        creditPoint.setCpStaticPoint(creditPoint.getCpStaticPoint() + profit);

        if (consumeRecord.getCrRewardRemainCount() == 0) {
            //最后一次收益返还
            //可用静态积分增加全部返还金额
            if (creditPoint.getCpAvailableStaticPoint() + consumeRecord.getCrRewardSum()
                    > creditPoint.getCpStaticPoint()) {
                creditPoint.setCpAvailableStaticPoint(creditPoint.getCpStaticPoint());
            } else {
                creditPoint.setCpAvailableStaticPoint(
                        creditPoint.getCpAvailableStaticPoint() + consumeRecord.getCrRewardSum());
            }
            if (consumeRecord.getCrPointType() == PointTypeEnum.ORIGINAL_POINT.getValue()) {
                creditPoint.setCpCapitalPoint(
                        creditPoint.getCpCapitalPoint() - consumeRecord.getCrCustPoint());
            } else if (consumeRecord.getCrPointType() == PointTypeEnum.REPEAT_POINT.getValue()) {
                creditPoint.setCpInRepeatPoint(
                        creditPoint.getCpInRepeatPoint() - consumeRecord.getCrCustPoint());
            }
            creditPoint.setCpRepeatPoint(
                    creditPoint.getCpRepeatPoint() + consumeRecord.getCrCustPoint());
            //资本积分退回流水记录
            PointOrder pointOrder = new PointOrder();
            pointOrder.setTid(UUIDGenerator.getUUID());
            if (consumeRecord.getCrPointType() == PointTypeEnum.ORIGINAL_POINT.getValue()) {
                pointOrder.setPoAmount(creditPoint.getCpCapitalPoint());
                pointOrder.setPoPointType(PointTypeEnum.CAPITAL_POINT.getValue());
            } else if (consumeRecord.getCrPointType() == PointTypeEnum.REPEAT_POINT.getValue()) {
                pointOrder.setPoAmount(creditPoint.getCpInRepeatPoint());
                pointOrder.setPoPointType(PointTypeEnum.IN_REPEAT_POINT.getValue());
            }
            pointOrder.setPoCreateDate(DateUtils.getNow());
            pointOrder.setPoDescription(
                    consumeRule.getCrDescription() + "，在投退回：-" + consumeRecord.getCrCustPoint());
            pointOrder.setPoFromUser(consumeRecord.getCrUser());
            pointOrder.setPoOrderno(orderNo);
            pointOrder.setPoToUser(consumeRecord.getCrUser());
            pointOrder.setPoTransPoint(consumeRecord.getCrCustPoint() * -1);
            pointOrder.setPoType(TransTypeEnum.TRANSFER.getValue());
            pointOrderBiz.add(pointOrder);

            //到期资本增加
            PointOrder reversePointOrder = new PointOrder();
            reversePointOrder.setTid(UUIDGenerator.getUUID());
            reversePointOrder.setPoAmount(creditPoint.getCpRepeatPoint());
            reversePointOrder.setPoCreateDate(DateUtils.getNow());
            reversePointOrder.setPoDescription(
                    consumeRule.getCrDescription() + "，到期：" + consumeRecord.getCrCustPoint());
            reversePointOrder.setPoFromUser(consumeRecord.getCrUser());
            reversePointOrder.setPoOrderno(orderNo);
            reversePointOrder.setPoPointType(PointTypeEnum.REPEAT_POINT.getValue());
            reversePointOrder.setPoToUser(consumeRecord.getCrUser());
            reversePointOrder.setPoTransPoint(consumeRecord.getCrCustPoint());
            reversePointOrder.setPoType(TransTypeEnum.TRANSFER.getValue());
            pointOrderBiz.add(reversePointOrder);

            logger.info(nowStr + "投资到期，积分变动订单号！【" + orderNo + "】");

            //用户未在投
            user.setUserInvesting(UserInvestStatusEnum.NOT_INVEST.getValue());
            userBiz.Update(user);

            //用户个人业绩回退
            if (creditPoint.getCpPerformancePoint() >= consumeRecord.getCrCustPoint()) {
                creditPoint.setCpPerformancePoint(
                        creditPoint.getCpPerformancePoint() - consumeRecord.getCrCustPoint());
            } else {
                creditPoint.setCpPerformancePoint(0);
            }
            //只有在原始积分投资的情况下，才回退团队业绩
//            if (consumeRecord.getCrPointType() == PointTypeEnum.ORIGINAL_POINT.getValue()) {
            processTeamPerformance(user, consumeRecord.getCrCustPoint());
//            }
        }
        int updateCount = creditPointBiz.update(creditPoint);
        if (updateCount <= 0) {
            throw new HkfsBizException(ErrorCodeEnum.CONCURRENT_MODIFY.getCode(),
                    ErrorCodeEnum.CONCURRENT_MODIFY.getMessage());
        }

        logger.info(nowStr + "静态积分分红，用户：" + user.getUserCode() + "");

        //增加静态收益记录
        benefitRecord = new BenefitRecord();
        benefitRecord.setTid(UUIDGenerator.getUUID());
        benefitRecord.setBrConsumeId(consumeRecord.getTid());
        benefitRecord.setBrOrderno(orderNo);//订单流水号
        benefitRecord.setBrRewardDate(DateUtils.getNowDateShort());
        benefitRecord.setBrUser(consumeRecord.getCrUser());
        benefitRecord.setBrRate(interestOfBeforeDay.getInterest());
        benefitRecord.setBrRewardPoint(profit);
        benefitRecordBiz.add(benefitRecord);
        logger.info(nowStr + "静态积分分红，静态收益记录订单号：【" + orderNo + "】");

        //增加积分变动流水记录 用户为正数
        PointOrder pointOrder = new PointOrder();
        pointOrder.setTid(UUIDGenerator.getUUID());
        pointOrder.setPoAmount(creditPoint.getCpStaticPoint());
        pointOrder.setPoCreateDate(DateUtils.getNow());
        pointOrder.setPoDescription(consumeRule.getCrDescription() + "，静态分红：" + profit);
        pointOrder.setPoFromUser("0");
        pointOrder.setPoOrderno(orderNo);
        pointOrder.setPoPointType(PointTypeEnum.STATIC_POINT.getValue());
        pointOrder.setPoToUser(consumeRecord.getCrUser());
        pointOrder.setPoTransPoint(profit);
        pointOrder.setPoType(TransTypeEnum.PROFIT.getValue());
        pointOrderBiz.add(pointOrder);

        //系统为负数
        PointOrder reversePointOrder = new PointOrder();
        reversePointOrder.setTid(UUIDGenerator.getUUID());
        reversePointOrder.setPoAmount(0);
        reversePointOrder.setPoCreateDate(DateUtils.getNow());
        reversePointOrder.setPoDescription(consumeRule.getCrDescription() + "，系统支出静态分红：-" + profit);
        reversePointOrder.setPoFromUser(consumeRecord.getCrUser());
        reversePointOrder.setPoOrderno(orderNo);
        reversePointOrder.setPoPointType(PointTypeEnum.STATIC_POINT.getValue());
        reversePointOrder.setPoToUser("0");
        reversePointOrder.setPoTransPoint(profit * -1);
        reversePointOrder.setPoType(TransTypeEnum.PROFIT.getValue());
        pointOrderBiz.add(reversePointOrder);

        logger.info(nowStr + "静态积分分红，积分变动订单号！【" + orderNo + "】");
    }

    /**
     * 递归处理用户的上级的团队业绩
     */
    private void processTeamPerformance(User curUser, double amount) throws HkfsBizException {

        if (curUser == null || StringUtils.isBlank(curUser.getUserParent()) || curUser
                .getUserParent().equals("0")) {
            return;
        }

        //获取上一级
        User upUser = userBiz.getUser(curUser.getUserParent());
        if (upUser == null) {
            return;
        }
        //上一级的积分
        CreditPoint upCreditPoint = creditPointBiz.getCreditPoint(upUser.getTid());
        if (upCreditPoint == null) {
            return;
        }
        if (upCreditPoint.getCpTeamPoint() >= amount) {
            upCreditPoint.setCpTeamPoint(upCreditPoint.getCpTeamPoint() - amount);
        } else {
            upCreditPoint.setCpTeamPoint(0);
        }
        int updateCount = creditPointBiz.update(upCreditPoint);
        if (updateCount <= 0) {
            throw new HkfsBizException(ErrorCodeEnum.CONCURRENT_MODIFY.getCode(),
                    ErrorCodeEnum.CONCURRENT_MODIFY.getMessage());
        }
        processTeamPerformance(upUser, amount);
    }
}
